package com.example.eshop_ssm.util;

import org.apache.ibatis.session.SqlSession;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 动态代理类（接口代理！！）
 */
public class MyMapperProxy {


    /**
     * 代理一切接口，帮它生成对象
     * @param clazz     要代理的接口类
     * @param <T>       要代理的接口类的泛型名称
     * @return   返回实现了clazz这个接口类的代理对象
     */
    public static <T> T createInstance(Class<T> clazz){

        //java.lang.refrect包下的类Proxy【反射机制提供的动态代理】
        //接口类的代理对象 obj = Proxy.newProxyInstance(类加载器,要代理的接口类,方法调用处理器);
        T obj = (T) Proxy.newProxyInstance(
                MyMapperProxy.class.getClassLoader(),
                new Class[]{clazz},
                new MyInvocationHandler(clazz)
                );
        ////上面返回的这个obj对象就是实现了clazz这个参数的接口的对象
        return obj;


    }


    /**
     * 方法调用处理器
     */
    private static class  MyInvocationHandler implements InvocationHandler{

        private Class clazz;

        public MyInvocationHandler(Class clazz){
            this.clazz = clazz;
        }

        //////这个invoke方法//////
        //当外部调用obj.careBaby();
        //当外部调用obj.cooking();
        ///就会回调这个invoke方法//
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //Method method   当前正在调用的方法
            //Object[] args   调用方法传递的参数值列表
            //System.out.println("当前正在调用的方法是>>>>"+method);

            SqlSession session = GetUtilSqlSessionFactory.getFactory().openSession();

            //StudentMapper obj = session.getMapper(StudentMapper.class);
            //List<StudentInfo> list = obj.selectListBySearch2(name);
            Object obj = session.getMapper(clazz);
            Object returnValue = method.invoke(obj,args);

            session.commit();
            session.close();
            return returnValue;
        }
    }



}



